package gql

import (
	"gitee.com/gopher2011/graph-ql-demo/mapper"
	"github.com/graphql-go/graphql"
)

/*  创建 Schema(类似于查询和映射规则)，并指定 Fields 和 Fields 中的 Resolver
	Resolver: GraphQL从何处取到数据(解析数据)
	Fields: GraphQL映射的数据域
 */

// 定义一个 Root 类，其中包括了一个 graphql.Object 类型的对象，即一个GraphQL的映射对象，这个对象就是一个 Schema
type Root struct {
	Query *graphql.Object
}

// User describes a graphql object containing a User
// Fields 规定了 GraphQL 的查询域，并且 Fields 是可以嵌套的
// http请求返回数据中，对象的描述
var User = graphql.NewObject(
	graphql.ObjectConfig{
		Name: "User",
		Fields: graphql.Fields{
			"id": &graphql.Field{
				Type: graphql.Int,
			},
			"name": &graphql.Field{
				Type: graphql.String,
			},
			"age": &graphql.Field{
				Type: graphql.Int,
			},
			"profession": &graphql.Field{
				Type: graphql.String,
			},
			"friendly": &graphql.Field{
				Type: graphql.Boolean,
			},
		},
	},
)
// NewRoot returns base query type. This is where we add all the base queries
func NewRoot(db *mapper.Db) *Root {
	resolver := Resolver{db: db}

	// Create a new Root that describes our base query set up. In this
	// example we have a user query that takes one argument called name
	root := Root{
		Query: graphql.NewObject(
			graphql.ObjectConfig{
				Name: "Query",	// GraphQL映射对象名称为: Query
				/*
				  Fields 中包扩了三个字段:
					Type: 返回类型
				    Args: 请求入参名及类型
					Resolver: 数据解析来源
				*/
				Fields: graphql.Fields{  // Fields 规定了 GraphQL 的查询域，并且 Fields 是可以嵌套的
					"users": &graphql.Field{
						Type: graphql.NewList(User), // User 为上面代码中定义的 GraphQL 映射类
						Args: graphql.FieldConfigArgument{
							"name": &graphql.ArgumentConfig{
								Type: graphql.String,
							},
						},
						// Create a resolver holding our database. Resolver can be found in resolvers.go
						// 数据解析函数
						Resolve: resolver.UserResolver,
					},
				},
			},
		),
	}
	return &root
}

// 上述的定义类似于:
/*
 	"users": [
		{
			"age": 35,
			"friendly": true,
			"id": 1,
			"name": "kevin",
			"profession": "waiter"
		},
		{
			"age": 15,
			"friendly": true,
			"id": 5,
			"name": "kevin",
			"profession": "in school"
		}
	]
*/

